/*
 * Created by kopper on 01.02.15 08:42
 * (C) Copyright 2015 kopperek@gmail.com
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 */

package app.android.kopper.gpxdownloader.parser;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Date;

import app.android.kopper.gpxdownloader.IUtilProvider;
import app.android.kopper.gpxdownloader.ProgressParam;
import app.android.kopper.gpxdownloader.R;

public class GR245Parser extends AbstractParser {


    public GR245Parser(File file,long fileSize) {
        super(file, fileSize);
    }

    PointDef parseItem(byte[] itemDef) throws IOException {
		Date utc = new Date(extractLong(Arrays.copyOfRange(itemDef,0,4))*1000);
		float lat = ByteBuffer.wrap(Arrays.copyOfRange(itemDef,4,8)).order(ByteOrder.LITTLE_ENDIAN ).getFloat();
		float lon = ByteBuffer.wrap(Arrays.copyOfRange(itemDef,8,12)).order(ByteOrder.LITTLE_ENDIAN ).getFloat();
		//speed and height are ignored
		return(new PointDef(utc,lat,lon));
	}
	
	protected void performParsing(IUtilProvider utils) throws IOException, FileNotFoundException {
		
		String gpxFileName=null;
		PrintWriter gpxWriter=null; 

		loop:
		for(;;) {
			if(available()<=0)
				break;
            utils.publishProgress(new ProgressParam(utils.getString(R.string.progress_parsing),"",(int)(filePos>>10),(int)(fileSize>>10)));
			loadArray(0x200,utils);
			
			for(;;) {
				if((filePos>>16)!=((filePos+7)>>16)) {
					seekTo(((filePos>>16)+1)<<16,utils);
					continue loop;
				}
				byte[] commandArray = loadArray(7,utils);
//				dumpArray(commandArray);
				if((Arrays.equals(commandArray,new byte[]{(byte)0xaa,(byte)0xaa,(byte)0xaa,(byte)0xaa,(byte)0xaa,(byte)0xaa,(byte)0xaa}))) {
					//command
					byte[] commandArgs = loadArray(9,utils);
					if (commandArgs[0]==0x07) { //on/off
						if(commandArgs[1]==0x04) {//off
							if(gpxWriter!=null) {
								
								closeGpxWriter(gpxWriter);
								gpxWriter=null;
							}
							
						} else if(commandArgs[1]==0x06) { //on
							if(gpxFileName!=null) {
								gpxWriter = createGpxWriter(gpxFileName,utils);
							}
						}
					}
				} else if((Arrays.equals(commandArray,new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff}))) {
					seekTo(((filePos>>16)+1)<<16,utils);
					continue loop;
				} else if((Arrays.equals(commandArray,"HOLUXGR".getBytes()))) {
					//any action ?
					loadArray(13,utils);
				} else {
					//item
					byte[] itemDef = new byte[20];
					System.arraycopy(commandArray,0,itemDef,0,7);
					System.arraycopy(loadArray(13,utils),0,itemDef,7,13);
//					dumpArray(itemDef);
					PointDef item = parseItem(itemDef);
					if(gpxWriter==null)
						gpxFileName=createGpxFileName(item);
					else {
						if(gpxWriter!=null) {
							writeTrackPoint(gpxWriter, item);
						}
					}
				}
			}
		}
	}
}
